﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Framework.Common.Attributes;
using System.Collections;
using System.Globalization;

namespace Framework.Common
{
    /// <summary>
    /// EnumHelper
    /// </summary>
    public static class EnumHelper
    {
        #region GetDescription

        /// <summary>
        /// 获取描述信息
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetDescription(this Enum e)
        {
            Type type = e.GetType();
            var desc = GetEnumDictionary(type)[e];
            return desc == null ? e.ToString() : desc.Description;
        }

        /// <summary>
        /// 获取对应的值
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T GetValue<T>(this Enum e)
        {
            Type type = e.GetType();
            var desc = GetEnumDictionary(type)[e];
            return desc == null ? default(T) : (T)desc.Value;
        }

        /// <summary>
        /// 获取枚举字典
        /// </summary>
        /// <typeparam name="TEnum"></typeparam>
        /// <returns></returns>
        public static Dictionary<Enum, OrderedDescAttribute> GetEnumDictionary<TEnum>()
        {
            return GetEnumDictionary(typeof(TEnum));
        }

        /// <summary>
        /// 获取枚举字典
        /// </summary>
        /// <param name="enumType"></param>
        /// <returns></returns>
        public static Dictionary<Enum, OrderedDescAttribute> GetEnumDictionary(Type enumType)
        {
            if (!allEnumDictionary.ContainsKey(enumType))
            {
                lock (locker)
                {
                    if (!allEnumDictionary.ContainsKey(enumType))
                    {
                        FieldInfo[] fis = enumType.GetFields(BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Public);
                        var enumDict = new Dictionary<Enum, OrderedDescAttribute>();
                        foreach (var fieldInfo in fis)
                        {
                            var key = (Enum)Convert.ChangeType(fieldInfo.GetValue(enumType), enumType, CultureInfo.InvariantCulture);
                            var value = (OrderedDescAttribute)fieldInfo.GetCustomAttributes(enumDescType, true).FirstOrDefault();
                            if (!enumDict.ContainsKey(key))
                            {
                                enumDict.Add(key, value);
                            }
                        }
                        allEnumDictionary.Add(enumType, enumDict);
                    }
                }
            }
            return allEnumDictionary[enumType];
        }
        #endregion

        #region 获取枚举值
        /// <summary>
        /// 获取枚举值
        /// </summary>
        /// <typeparam name="TEnum"></typeparam>
        /// <param name="input"></param>
        /// <returns></returns>
        public static TEnum GetEnum<TEnum>(string input) where TEnum : struct
        {
            TEnum te;
            if (Enum.TryParse<TEnum>(input, true, out te))
            {
                return te;
            }
            return default(TEnum);
        }
        #endregion

        #region static member
        /// <summary>
        /// 
        /// </summary>
        static Dictionary<Type, Dictionary<Enum, OrderedDescAttribute>> allEnumDictionary
            = new Dictionary<Type, Dictionary<Enum, OrderedDescAttribute>>();

        /// <summary>
        /// locker
        /// </summary>
        static object locker = new object();

        /// <summary>
        /// default enum desc type
        /// </summary>
        static Type enumDescType = typeof(OrderedDescAttribute);
        #endregion
    }


}
